package main

import (
	"fmt"
	"log"
	"runtime"
)

var intMap map[int]int
var cnt = 8192

func main() {
	foo2()
}

func foo2() {
	printMemStats()
	initMapData()
	runtime.GC()
	printMemStats()
	log.Println(len(intMap))
	for i := 0; i < cnt; i++ {
		delete(intMap, i)
	}
	log.Println(len(intMap))
	runtime.GC()
	printMemStats()
	printMemStats()
	intMap = nil
	runtime.GC()
	printMemStats()
}
func initMapData() {
	intMap = make(map[int]int, cnt)
	for i := 0; i < cnt; i++ {
		x := i
		intMap[i] = x
	}
}
func printMemStats() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	log.Printf("Alloc = %v TotalAlloc = %v Sys = %v NumGC = %v\n", m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)

	// 字段说明：
	// Alloc： 当前堆上对象占用的内存大小;
	// TotalAlloc：堆上总共分配出的内存大小;
	// Sys： 程序从操作系统总共申请的内存大小;
	// NumGC： 垃圾回收运行的次数。
}

func foo() {
	n := 1_000_000
	m := make(map[int][128]byte)
	printAlloc()

	for i := 0; i < n; i++ { // Adds 1 million elements
		m[i] = [128]byte{'1'}
	}
	printAlloc()

	for i := 0; i < n; i++ { // Deletes 1 million elements
		delete(m, i)
	}

	runtime.GC() // Triggers a manual GC
	printAlloc()
	runtime.KeepAlive(m) // Keeps a reference to m so that the map isn’t collected
}

func foo3() {
	n := 1_000_000

	printAlloc()

	for i := 0; i < n; i++ { // Adds 1 million elements
		intMap[i] = i
	}
	printAlloc()

	for i := 0; i < n; i++ { // Deletes 1 million elements
		delete(intMap, i)
	}

	runtime.GC() // Triggers a manual GC
	printAlloc()
	runtime.KeepAlive(intMap) // Keeps a reference to m so that the map isn’t collected
}

func printAlloc() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	fmt.Printf("%d KB\n", m.Alloc/1024)
}
